﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
using Fine.CRM.Common;
using ProxyClasses;


/// <summary>
/// Moves all email attachments on the target email from CRM storage to Azure blob storage. Writes result of activity to 
/// the Activity Status output parameter.
/// </summary>
public class EmailAttachmentsToCloud : WorkflowActivity
{

    [Output("Activity Status")]
    public OutArgument<string> ActivityStatus { get; set; }

    public EmailAttachmentsToCloud()
        : base(typeof(EmailAttachmentsToCloud))
    {
        base.RegisteredEvents.Add(new Action<LocalWorkflowContext>(Execute));
    }

    protected void Execute(LocalWorkflowContext localContext)
    {
        try
        {
            EntityReference regardingId = new EntityReference(localContext.WorkflowContext.PrimaryEntityName, localContext.WorkflowContext.PrimaryEntityId);
            AzureSettings settings = new AzureSettings(localContext.XmlConfigurationResources);

            QueryExpression qry = new QueryExpression
            {
                EntityName = activitymimeattachment.GetLogicalName(),
                ColumnSet = new ColumnSet(true),
                Criteria = new FilterExpression
                {
                    FilterOperator = LogicalOperator.And,
                    Conditions = 
                    {
                        new ConditionExpression {
                            AttributeName = activitymimeattachment.Properties.objectid,
                            Operator = ConditionOperator.Equal,
                            Values = {regardingId.Id}
                        },
                        new ConditionExpression {
                            AttributeName = activitymimeattachment.Properties.filename,
                            Operator = ConditionOperator.DoesNotBeginWith,
                            Values = {settings.FileNamePrefix}
                        }
                    }
                }
            };

            EntityCollection results = localContext.OrganizationService.RetrieveMultiple(qry);

            foreach (Entity record in results.Entities)
            {
                string filename = record.GetAttributeValue<string>(activitymimeattachment.Properties.filename);
                string body = record.GetAttributeValue<string>(activitymimeattachment.Properties.body);

                MimeAttachmentHandler.PutAzureBlob(settings, record.Id, body);

                filename = settings.FileNamePrefix + filename;

                Entity updateRecord = new Entity(activitymimeattachment.GetLogicalName());
                updateRecord.Id = record.Id;
                updateRecord.AddUpdateAttribute(activitymimeattachment.Properties.filename, filename);
                updateRecord.AddUpdateAttribute(activitymimeattachment.Properties.body, settings.FilePlaceHolderText);
                localContext.OrganizationService.Update(updateRecord);
            }

            ActivityStatus.Set(localContext.ExecutionContext, string.Format("Success - {0} attachments moved to cloud storage", results.Entities.Count));


        }
        catch (Exception ex)
        {
            ActivityStatus.Set(localContext.ExecutionContext, string.Format("Error - {0}", ex.Message));
        }

    }

}

/// <summary>
/// Move all email attachments on the target email from Azure blob storage back to CRM storage. Writes result of activity to 
/// the Activity Status output parameter.
/// </summary>
public class EmailAttachmentsFromCloud : WorkflowActivity
{

    [Output("Activity Status")]
    public OutArgument<string> ActivityStatus { get; set; }

    public EmailAttachmentsFromCloud()
        : base(typeof(EmailAttachmentsFromCloud))
    {
        base.RegisteredEvents.Add(new Action<LocalWorkflowContext>(Execute));
    }

    protected void Execute(LocalWorkflowContext localContext)
    {
        try
        {
            EntityReference regardingId = new EntityReference(localContext.WorkflowContext.PrimaryEntityName, localContext.WorkflowContext.PrimaryEntityId);
            AzureSettings settings = new AzureSettings(localContext.XmlConfigurationResources);

            QueryExpression qry = new QueryExpression
            {
                EntityName = activitymimeattachment.GetLogicalName(),
                ColumnSet = new ColumnSet(true),
                Criteria = new FilterExpression
                {
                    FilterOperator = LogicalOperator.And,
                    Conditions = 
                    {
                        new ConditionExpression {
                            AttributeName = activitymimeattachment.Properties.objectid,
                            Operator = ConditionOperator.Equal,
                            Values = {regardingId.Id}
                        },
                        new ConditionExpression {
                            AttributeName = activitymimeattachment.Properties.filename,
                            Operator = ConditionOperator.BeginsWith,
                            Values = {settings.FileNamePrefix}
                        }
                    }
                }
            };

            EntityCollection results = localContext.OrganizationService.RetrieveMultiple(qry);

            foreach (Entity record in results.Entities)
            {
                string filename = record.GetAttributeValue<string>(activitymimeattachment.Properties.filename);
               
                string body = MimeAttachmentHandler.GetAzureBlob(settings, record.Id);
                filename = filename.Substring(settings.FileNamePrefix.Length);
               
                Entity updateRecord = new Entity(activitymimeattachment.GetLogicalName());
                updateRecord.Id = record.Id;
                updateRecord.AddUpdateAttribute(activitymimeattachment.Properties.filename, filename);
                updateRecord.AddUpdateAttribute(activitymimeattachment.Properties.body, body);
                localContext.OrganizationService.Update(updateRecord);

            }

            ActivityStatus.Set(localContext.ExecutionContext, string.Format("Success - {0} attachments moved from cloud storage to CRM storage.", results.Entities.Count));

        }
        catch (Exception ex)
        {
            ActivityStatus.Set(localContext.ExecutionContext, string.Format("Error - {0}", ex.Message));
        }

    }

}